#include <Arduino.h>
#include "WiFi.h"
#include "HTTPClient.h"
#include <ArduinoJson.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include <ir_Gree.h>

const uint16_t kIrLed = 15;  // ESP8266 GPIO pin to use. Recommended: 4 (D2).
IRGreeAC ac(kIrLed);  // Set the GPIO to be used for sending messages.
//IR 3v3 GPIO17 GND

const char *ssid = "XXXXXXXXXXXX";       //wifi名称
const char *password = "XXXXXXXXX";   //wifi密码
const char *host = "http://127.0.0.1"; //

WiFiClient wifi_Client;
HTTPClient http_client,http_rets,http_rete;
String req,req2,req3;
String rsp,rsp2,rsp3;
int commaposition;

String acpower,acmode,temperature,fanspeed,lightmode,turbomode,sleepmode;
bool ac_light,ac_turbo,ac_sleep;
//Wifi
void setupWifi()
{
  delay(10);
  Serial.println("connecting WIFI");
  WiFi.begin(ssid, password);
  while (!WiFi.isConnected())
  {
    Serial.print(".");
    delay(1000);
  }
  set_Light("on");
  delay(1500);
  set_Light("off");
  delay(500);
  set_Light("on");
  delay(2000);
  set_Light("off");
  Serial.println("OK");
  Serial.println("Wifi connected");
}

void setUpHttpClient()
{
  req = (String)host + "/get_json";
  req2 = (String)host + "/espCallback?type=success";
  req3 = (String)host + "/espCallback?type=error";
  if (http_client.begin(req))
  {
    Serial.println("HTTPclient setUp done!");
  }
  if (http_rets.begin(req2))
  {
    Serial.println("HTTPreturnSuccess setUp done!");
  }
  if (http_rete.begin(req3))
  {
    Serial.println("HTTPreturnError setUp done!");
  }
}

void setup()
{
  Serial.begin(115200);
  delay(1000);
  setupWifi();
  setUpHttpClient();
}

void loop()
{
  int http_code = http_client.GET();
  if (http_code > 0)
  {
    Serial.printf("HTTP get code: %d\n", http_code);
    if (http_code == HTTP_CODE_OK)
    {
      set_Light("on");
      rsp = http_client.getString();
      Serial.println(rsp);
      DynamicJsonDocument  jsonBuffer(200);
      deserializeJson(jsonBuffer, rsp);
      JsonObject root = jsonBuffer.as<JsonObject>();
      String info = root["info"];
      String datatype = root["type"];
      if(datatype == "cmd"){
        String cmd = root["cmd"];
        handlecmd(cmd);
       }
    }
    else
    {
      Serial.printf("fail to get json,code:%d\n", http_code);
    }
  }
  
  delay(1000);
  set_Light("off");
  delay(3000);
}

void handlecmd(String cmd){
  Serial.println("exec cmd.."+cmd);
  if(cmd == "lighton"){
    LightCtrl("on");
  } else if (cmd == "lightoff") { 
    LightCtrl("off");
  }else if (cmd.substring(0,7) == "closeac") { 
    ac_close();
  }else if (cmd.substring(0,6) == "openac") {
    commaposition = cmd.indexOf(';');
    acpower =cmd.substring(0,commaposition);
    cmd = cmd.substring(commaposition+1,cmd.length());

    commaposition = cmd.indexOf(';');
    acmode =cmd.substring(0,commaposition);
    cmd = cmd.substring(commaposition+1,cmd.length());
    
    commaposition = cmd.indexOf(';');
    temperature =cmd.substring(0,commaposition);
    cmd = cmd.substring(commaposition+1,cmd.length());
    
    commaposition = cmd.indexOf(';');
    fanspeed =cmd.substring(0,commaposition);
    cmd = cmd.substring(commaposition+1,cmd.length());

    commaposition = cmd.indexOf(';');
    lightmode =cmd.substring(0,commaposition);
    cmd = cmd.substring(commaposition+1,cmd.length());

    commaposition = cmd.indexOf(';');
    turbomode =cmd.substring(0,commaposition);
    sleepmode = cmd.substring(commaposition+1,cmd.length());
    if(lightmode=="lingtoff"){
      ac_light=false;
     }else{
        ac_light=true;
     }
     if(turbomode=="turboon"){
        ac_turbo=true;
     }else{
        ac_turbo=false;
     }
     if(sleepmode=="sleepon"){
        ac_sleep=true;
     }else{
        ac_sleep=false;
     }
    Serial.println("acmode="+acmode);
    Serial.println("temperature="+temperature);
    Serial.println("fanspeed="+fanspeed);
    Serial.println("lightmodeD="+lightmode);
    Serial.println("turbomode="+turbomode);
    Serial.println("sleepmode="+sleepmode);
    
    ir_remote(acmode,temperature.toInt(),fanspeed.toInt(),ac_light,ac_turbo,ac_sleep);
  }
  else {
    sendresult("error");
  }
}
void sendresult(String flag){
  if(flag == "success"){
    int http_code2 = http_rets.GET();
    if (http_code2 > 0){
      if (http_code2 == HTTP_CODE_OK){
        rsp2 = http_rets.getString();
        Serial.println("exec SUCCESS..retun success");
      }
      else{
        Serial.printf("fail to get json,code:%d\n", http_code2);
      }
    } 
  }else if (flag == "error") { 
    int http_code3 = http_rete.GET();
    if (http_code3 > 0){
      if (http_code3 == HTTP_CODE_OK){
        rsp3 = http_rete.getString();
        Serial.println("exec ERROR..retun success");
      }
      else{
        Serial.printf("fail to get json,code:%d\n", http_code3);
      }
    }
   }
}
void LightCtrl(String flag2){
  if(flag2 == "on"){
    pinMode(2, OUTPUT);
    digitalWrite(2, HIGH);
    sendresult("success");
   }else {
      pinMode(2, OUTPUT);
      digitalWrite(2, LOW);
      sendresult("success");
    }
}
void set_Light(String flag4){
  if(flag4 == "on"){
    pinMode(2, OUTPUT);
    digitalWrite(2, HIGH);
   }else {
      pinMode(2, OUTPUT);
      digitalWrite(2, LOW);
    }
}
void ir_remote(String acmode,int actmp,int fanspeed,bool aclight,bool acturbo,bool acsleep){
    ac.begin();
    //printState()
    ac.on();
    ac.setFan(fanspeed);
    if(acmode=="cool"){
      ac.setMode(kGreeCool);// kGreeAuto, kGreeDry, kGreeCool, kGreeFan, kGreeHeat
    }else if(acmode=="heat"){
      ac.setMode(kGreeHeat);
    }else if(acmode=="dry"){
      ac.setMode(kGreeDry);
    }else if(acmode=="fan"){
      ac.setMode(kGreeFan);
    }else{
      ac.setMode(kGreeCool);
    }
    ac.setTemp(actmp);  // 16-30C
    ac.setSwingVertical(false, kGreeSwingAuto); //(true, kGreeSwingAuto)
    ac.setXFan(false);
    ac.setLight(aclight);//light:true/false
    ac.setSleep(acsleep);
    ac.setTurbo(acturbo);
    ac.send();
    sendresult("success");
}
void ac_close(){
      ac.begin();
      //printState()
      ac.off();
      ac.send();
      sendresult("success");
}



void printState() {
  // Display the settings.
  Serial.println("GREE A/C remote is in the following state:");
  Serial.printf("  %s\n", ac.toString().c_str());
  // Display the encoded IR sequence.
  unsigned char* ir_code = ac.getRaw();
  Serial.print("IR Code: 0x");
  for (uint8_t i = 0; i < kGreeStateLength; i++)
    Serial.printf("%02X", ir_code[i]);
  Serial.println();
}
